package com.wuhongyu.heap;

import java.util.ArrayList;


/**
 * 最大堆
 * @param <E>
 */
public class MaxHeap<E extends Comparable<E>> {

    private ArrayList<E> data;

    public MaxHeap(int capacity){
        data = new ArrayList<>(capacity);
    }

    public MaxHeap(){
        data = new ArrayList<>();
    }
    public boolean isEmpty(){
        return data.size() ==0;
    }

    public int size(){
        return data.size();
    }

    private int parent(int i){
        return (i-1)/2;
    }

    private int getLeftChild(int i){
        return i*2+1;
    }

    private int getRightChild(int i){
        return i*2+2;
    }

    public void insert(E e){
        data.add(e);
        siftUp(data.size());
    }

    private void siftUp(int k) {
        while(k>1 && data.get(k).compareTo(data.get(parent(k)))<0){
            swap(k,parent(k));
            k = parent(k);
        }
    }

    public E findMax(){
        if(data.size() == 0){
            throw new IllegalArgumentException("堆为空");
        }
        return data.get(0);
    }

    public E extraMax(){
        E result = findMax();
        //将最后一个元素赋值给第一个元素
        data.set(0,data.get(data.size()-1));
        data.remove(data.remove(data.size()-1));
        siftDown(0);
        return result;
    }

    private void siftDown(int k) {
        while(getLeftChild(k) < data.size()){
            int leftChild = getLeftChild(k);
            if(leftChild+1 < data.size() && data.get(leftChild+1).compareTo(data.get(leftChild))<0){
                leftChild++;
            }
            //下标k的值与他左右孩子中最大的值比较  如果大于 就break
            if(data.get(leftChild).compareTo(data.get(k))<=0){
                break;
            }
            swap(leftChild,k);
            k = leftChild;
        }
    }

    private void swap(int i,int j){
        E e = data.get(i);
        data.set(i,data.get(j));
        data.set(j,e);
    }
}